package demo.hdz.libstreamingdemo;

import net.majorkernelpanic.streaming.Session;
import net.majorkernelpanic.streaming.SessionBuilder;
import net.majorkernelpanic.streaming.audio.AudioQuality;
import net.majorkernelpanic.streaming.gl.SurfaceView;
import net.majorkernelpanic.streaming.rtsp.RtspServer;
import net.majorkernelpanic.streaming.video.VideoQuality;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * A straightforward example of how to stream AMR and H.263 to some public IP using libstreaming.
 * Note that this example may not be using the latest version of libstreaming !
 */
public class MainActivity extends Activity implements OnClickListener, Session.Callback, SurfaceHolder.Callback {

    private final static String TAG = "MainActivity";
    private static final int PERMISSION_REQUEST_CODE = 1102;
    private static final int RTSP_PORT = 1234;

    private SurfaceView mSurfaceView;
    private Session mSession;
    private String  m_sLocalIP;

    private MediaPlayer mMediaPlayer;
    private android.view.SurfaceView mPlaySurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        Button mButton1 = (Button) findViewById(R.id.btnStart);
        Button mButton2 = (Button) findViewById(R.id.btnStop);
        mButton1.setOnClickListener(this);
        mButton2.setOnClickListener(this);

        Button localPlay = (Button)findViewById(R.id.btnLocalPlay);
        localPlay.setOnClickListener(this);

        mSurfaceView = (SurfaceView) findViewById(R.id.surface);

        AskForPermission();

        mSession = SessionBuilder.getInstance()
                .setCallback(this)
                .setSurfaceView(mSurfaceView)
                .setPreviewOrientation(90)
                .setContext(getApplicationContext())
                .setAudioEncoder(SessionBuilder.AUDIO_NONE)
                .setAudioQuality(new AudioQuality(16000, 32000))
                .setVideoEncoder(SessionBuilder.VIDEO_H264)
                .setVideoQuality(new VideoQuality(320,240,20,500000))
                .build();

        mSurfaceView.getHolder().addCallback(this);

        m_sLocalIP = getWifiIP();
        TextView tv = (TextView) findViewById(R.id.tvLocalIP);
        tv.setText("rtsp://"+m_sLocalIP+":"+RTSP_PORT);

        SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
        editor.putString(RtspServer.KEY_PORT, String.valueOf(RTSP_PORT));
        editor.commit();


        mMediaPlayer = new MediaPlayer();
        mPlaySurfaceView = (android.view.SurfaceView)findViewById(R.id.playSurfaceView);
        mPlaySurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                mMediaPlayer.setDisplay(holder);
            }
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {}
        });
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mSession.release();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnStart:
                startServer();
                break;
            case R.id.btnStop:
                stopServer();
                break;
            case R.id.btnLocalPlay:
                localPlay();
                break;
            default:
                mSession.switchCamera();
                break;
        }
    }

    private void startServer() {
        Toast.makeText(this, "开始RTSP服务", Toast.LENGTH_SHORT).show();
        mSession.setDestination(m_sLocalIP);
        if (!mSession.isStreaming()) {
            mSession.configure();
            startService(new Intent(this, RtspServer.class));
        }
    }
    private void localPlay() {
        Toast.makeText(this, "本地播放", Toast.LENGTH_SHORT).show();
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(String.valueOf(Uri.parse("rtsp://" + m_sLocalIP + ":" + RTSP_PORT)));
            mMediaPlayer.prepare();
            mMediaPlayer.start();
        } catch (Exception e) {
            e.printStackTrace();
            logError("播放失败："+e.getMessage());
        }
    }

    private void stopServer() {
        Toast.makeText(this, "停止RTSP服务", Toast.LENGTH_SHORT).show();
        if (mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
            mMediaPlayer.release();;
        }
        if (mSession.isStreaming()) {
            mSession.stop();
            stopService(new Intent(this, RtspServer.class));
        }
    }

    @Override
    public void onBitrateUpdate(long bitrate) {
        Logger.d(TAG,"Bitrate: "+bitrate, false);
    }

    @Override
    public void onSessionError(int message, int streamType, Exception e) {
        if (e != null) {
            logError(e.getMessage());
        }
    }

    @Override

    public void onPreviewStarted() {
        Log.d(TAG,"Preview started.");
    }

    @Override
    public void onSessionConfigured() {
        Log.d(TAG,"Preview configured.");
        // Once the stream is configured, you can get a SDP formated session description
        // that you can send to the receiver of the stream.
        // For example, to receive the stream in VLC, store the session description in a .sdp file
        // and open it with VLC while streming.
        Log.d(TAG, mSession.getSessionDescription());
        mSession.start();
    }

    @Override
    public void onSessionStarted() {
        Log.d(TAG,"Session started.");
    }

    @Override
    public void onSessionStopped() {
        Log.d(TAG,"Session stopped.");
    }

    /** Displays a popup to report the eror to the user */
    private void logError(final String msg) {
        final String error = (msg == null) ? "Error unknown" : msg;
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setMessage(error).setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {}
        });
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mSession.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mSession.stop();
    }




    private void AskForPermission(){
        if (Build.VERSION.SDK_INT >= 23) {
            List<String> permissionList = new ArrayList<>();
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(Manifest.permission.INTERNET);
            }
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(Manifest.permission.ACCESS_WIFI_STATE);
            }
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(Manifest.permission.RECORD_AUDIO);
            }
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(Manifest.permission.CAMERA);
            }
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WAKE_LOCK) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(Manifest.permission.WAKE_LOCK);
            }
            if (permissionList.size() > 0) {
                String[] permissions = permissionList.toArray(new String[permissionList.size()]);//将List转为数组
                ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
            }
        }
    }

    private String getWifiIP() {

        //获取WIFI管理服务
        @SuppressLint("WifiManagerLeak") WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

        //判断WIFI是否开启
        if (!wifiManager.isWifiEnabled()) {
            return "";
        }

        //获取WIFI信息，需要设置用户权限：android.permission.ACCESS_WIFI_STATE
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();

        //获得整型的IP地址
        int iIP = wifiInfo.getIpAddress();

        //将整型的IP地址转换为字符串类型的IP地址
        return Util.intToIP(iIP);
    }

}
